package com.jzo2o.market.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.*;
import com.jzo2o.market.constants.TabTypeConstants;
import com.jzo2o.market.enums.ActivityStatusEnum;
import com.jzo2o.market.mapper.ActivityMapper;
import com.jzo2o.market.model.domain.Activity;
import com.jzo2o.market.model.domain.Coupon;
import com.jzo2o.market.model.dto.request.ActivityQueryForPageReqDTO;
import com.jzo2o.market.model.dto.request.ActivitySaveReqDTO;
import com.jzo2o.market.model.dto.response.ActivityInfoResDTO;
import com.jzo2o.market.model.dto.response.SeizeCouponInfoResDTO;
import com.jzo2o.market.service.IActivityService;
import com.jzo2o.market.service.ICouponService;
import com.jzo2o.market.service.ICouponWriteOffService;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.mysql.utils.PageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.jzo2o.market.constants.RedisConstants.RedisKey.*;
import static com.jzo2o.market.enums.ActivityStatusEnum.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author itcast
 * @since 2023-09-16
 */
@Service
@Slf4j
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {
    private static final int MILLION = 1000000;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private ICouponService couponService;

    @Resource
    private ICouponWriteOffService couponWriteOffService;

    /**
     * 后台端查询活动列表
     *
     * @param reqDTO
     * @return
     */
    @Override
    public PageResult<Activity> queryActivityList(ActivityQueryForPageReqDTO reqDTO) {
        log.info("查询活动列表，参数：{}", reqDTO);
        Page<Activity> page = PageUtils.parsePageQuery(reqDTO, Activity.class);

        LambdaQueryWrapper<Activity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(reqDTO.getName()), Activity::getName, reqDTO.getName())
                .eq(reqDTO.getStatus() != null, Activity::getStatus, reqDTO.getStatus())
                .eq(reqDTO.getType() != null, Activity::getType, reqDTO.getType())
                .eq(reqDTO.getId() != null, Activity::getId, reqDTO.getId());
        Page<Activity> activityPage = super.page(page, queryWrapper);
        return PageUtils.toPage(activityPage, Activity.class);
    }

    /**
     * 后台端保存活动
     *
     * @param reqDTO
     */
    @Override
    public void saveActivity(ActivitySaveReqDTO reqDTO) {
        log.info("保存活动，参数：{}", reqDTO);
        if (reqDTO.getId() == null) {
            // 新增操作
            Activity activity = BeanUtils.copyProperties(reqDTO, Activity.class);
            // 设置生效状态
            activity.setStatus(ActivityStatusEnum.NO_DISTRIBUTE.getStatus());
            // 库存数量,当前默认等于发放数量
            activity.setStockNum(activity.getTotalNum());
            // 创建人
            activity.setCreateBy(UserContext.currentUserId());
            // 修改人
            activity.setUpdateBy(UserContext.currentUserId());
            super.save(activity);
        } else {
            // 修改操作
            Activity oldActivity = super.getById(reqDTO.getId());
            if (oldActivity == null) {
                throw new BadRequestException("活动不存在");
            }
            // 校验活动状态是否允许修改
            if (!oldActivity.getStatus().equals(ActivityStatusEnum.NO_DISTRIBUTE.getStatus())) {
                throw new BadRequestException("只有未分发状态的活动才能修改");
            }
            Activity activity = BeanUtils.copyProperties(reqDTO, Activity.class);
            // 更新人
            activity.setUpdateBy(UserContext.currentUserId());
            // 更新时间
            activity.setUpdateTime(LocalDateTime.now());

            super.updateById(activity);
        }
    }

    /**
     * 后台端撤销活动
     *
     * @param id
     */
    @Override
    @Transactional
    public void revokeActivity(Long id) {
        log.info("撤销活动，参数：{}", id);

        Activity activity = super.getById(id);

        if (activity == null) {
            throw new BadRequestException("活动不存在");
        }
        // 校验活动状态是否允许撤销 1.待生效 2.进行中
        if (activity.getStatus() == NO_DISTRIBUTE.getStatus() || activity.getStatus() == DISTRIBUTING.getStatus()) {
            // 先跟新活动表状态
            activity.setStatus(VOIDED.getStatus());
            super.updateById(activity);

            // 还需要更新优惠券表状态
            List<Coupon> couponList = couponService.list(Wrappers.<Coupon>lambdaQuery()
                    .eq(Coupon::getActivityId, id));
            if (CollectionUtils.isEmpty(couponList)) {
                return;
            }
            // 更新优惠券表状态
            couponList.forEach(coupon -> {
                coupon.setStatus(LOSE_EFFICACY.getStatus());
            });
            couponService.updateBatchById(couponList);
        }
    }
}
